package top.fwpsl.redis;

/**
 * hash 操作
 *
 * @auther: 风戏fw
 * @date: 2020/11/21
 */
public interface IJedisHashClient {

    /**
     * 删除哈希表 key 中的一个或多个指定域，不存在的域将被忽略
     * <p>
     * 时间复杂度： O(N)  N为要删除域的数量
     *
     * @param key
     * @param field
     * @return 被成功移除的域的数量，不包括被忽略的域
     */
    int hdel(String key, String... field);

    /**
     * 查看哈希表 key 中，给定域 field 是否存在
     * <p>
     * 时间复杂度： O(1)
     *
     * @param key
     * @param field
     * @return 如果哈希表含有给定域，返回 1; 如果哈希表不含有给定域，或 key 不存在，返回 0
     */
    byte hexists(String key, String field);

    /**
     * 返回哈希表 key 中给定域 field 的值
     * <p>
     * 时间复杂度： O(1)
     *
     * @param key
     * @param field
     * @return 给定域的值; 当给定域不存在或是给定 key 不存在时，返回 nil
     */
    Object hget(String key, String field);

    /**
     * 返回哈希表 key 中，所有的域和值。
     * 在返回值里，紧跟每个域名(field name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍。
     * <p>
     * 时间复杂度： O(N), N为哈希表的大小
     *
     * @param key
     * @return 以列表形式返回哈希表的域和域的值； 若 key 不存在，返回空列表
     */
    Object[] hgetall(String key);

    /**
     * 为哈希表 key 中的域 field 的值加上增量 increment 。
     * 增量也可以为负数，相当于对给定域进行减法操作。
     * 如果 key 不存在，一个新的哈希表被创建并执行 HINCRBY 命令。
     * 如果域 field 不存在，那么在执行命令前，域的值被初始化为 0 。
     * 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
     * 本操作的值被限制在 64 位(bit)有符号数字表示之内
     * <p>
     * 时间复杂度： O(1)
     *
     * @param key
     * @param field
     * @return 命令执行后，哈希表key中域field的值
     */
    long hincrby(String key, String field);

    /**
     * 为哈希表 key 中的域 field 加上浮点数增量 increment 。
     * 如果哈希表中没有域 field ，那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ，然后再执行加法操作。
     * 如果键 key 不存在，那么 HINCRBYFLOAT 会先创建一个哈希表，再创建域 field ，最后再执行加法操作。
     * <p>
     * 时间复杂度： O(1)
     *
     * @param key
     * @param field
     * @param increment
     * @return 命令执行后，哈希表key中域field的值
     */
    double hincrbyfloat(String key, String field, double increment);

    /**
     * 返回哈希表 key 中的所有域
     * <p>
     * 时间复杂度: O(N)， N 为哈希表的大小
     *
     * @param key
     * @return 一个包含哈希表中所有域的表; 当 key 不存在时，返回一个空表
     */
    String[] hkeys(String key);

    /**
     * 返回哈希表 key 中域的数量
     * <p>
     * 时间复杂度: O(1)
     *
     * @param key
     * @return 哈希表中域的数量; 当 key 不存在时，返回 0 。
     */
    int hlen(String key);

    /**
     * 返回哈希表 key 中，一个或多个给定域的值。
     * 如果给定的域不存在于哈希表，那么返回一个 nil 值。
     * 因为不存在的 key 被当作一个空哈希表来处理，所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表
     * <p>
     * 时间复杂度: O(N), N为给定域的数量
     *
     * @param key
     * @param field
     * @return 一个包含多个给定域的关联值的表，表值的排列顺序和给定域参数的请求顺序一样
     */
    String[] hmget(String key, String... field);

    /**
     * 同时将多个 field-value (域-值)对设置到哈希表 key 中。
     * 此命令会覆盖哈希表中已存在的域。
     * 如果 key 不存在，一个空哈希表被创建并执行 HMSET 操作
     * <p>
     * 时间复杂度: O(N), N为field-value对的数量
     *
     * @param key
     * @param fieldValues
     * @return 如果命令执行成功，返回 OK; 当 key 不是哈希表(hash)类型时，返回一个错误
     */
    boolean hmset(String key, String... fieldValues);

    /**
     * 将哈希表 key 中的域 field 的值设为 value 。
     * 如果 key 不存在，一个新的哈希表被创建并进行 HSET 操作。
     * 如果域 field 已经存在于哈希表中，旧值将被覆盖
     * <p>
     * 时间复杂度： O(1)
     *
     * @param key
     * @param field
     * @param value
     * @return 如果 field 是哈希表中的一个新建域，并且值设置成功，返回 1 。
     * 如果哈希表中域 field 已经存在且旧值已被新值覆盖，返回 0
     */
    byte hset(String key, String field, Object value);

    /**
     * 将哈希表 key 中的域 field 的值设置为 value ，当且仅当域 field 不存在。
     * 若域 field 已经存在，该操作无效。
     * 如果 key 不存在，一个新哈希表被创建并执行 HSETNX 命令
     * <p>
     * 时间复杂度: O(1)
     *
     * @param key
     * @param field
     * @param value
     * @return 设置成功，返回1; 如果给定域已经存在且没有操作被执行，返回0
     */
    int hsetnx(String key, String field, Object value);

    /**
     * 返回哈希表 key 中所有域的值
     *
     * 时间复杂度: O(N), N为哈希表的大小
     *
     * @param val
     * @return 一个包含哈希表中所有值的表; 当key不存在时，返回一个空表
     */
    String[] hvals(String val);



}
